/*
//              INTEL CORPORATION PROPRIETARY INFORMATION
//  This software is supplied under the terms of a license  agreement or
//  nondisclosure agreement with Intel Corporation and may not be copied
//  or disclosed except in  accordance  with the terms of that agreement.
//    Copyright (c) 2006-2007 Intel Corporation. All Rights Reserved.
//
*/
#include "umc_defs.h"
#if defined (UMC_ENABLE_DV_VIDEO_ENCODER)

#include "umc_dv_enc_compressor_def.h"
#include "umc_dv_enc_segment_compressor.h"
#include "umc_dv_enc_block.h"
#include "ippdefs.h"

namespace UMC
{

void ZigZagMBlock(BLOCK *lpBlocks, Ipp32u** RLmember);
inline static Ipp32s ZigZag0(Ipp32u** RLmem, Ipp16s *lpsDst,  Ipp8s * DeZigzag);

void SegmentCompressor::ZigZagData()
{
    Ipp32u * RLmemberSeg = m_VSegment.m_pDCTBlocks[0].m_lpsDataRL;
    Ipp32s MBNum;
    for(MBNum=0; MBNum<5; MBNum++)
        ZigZagMBlock(m_VSegment.m_pDCTBlocks + MBNum*m_nDCTBlocksInMB, &RLmemberSeg);
}

void ZigZagMBlock(BLOCK *lpBlocks, Ipp32u** RLmember)
{
    Ipp32s maxA[6];
    Ipp32s DCTBlockNum;
    for(DCTBlockNum=0; DCTBlockNum<6; DCTBlockNum++)
    {
        lpBlocks[DCTBlockNum].m_lpsDataRL = *RLmember;
        maxA[DCTBlockNum] = ZigZag0(RLmember, lpBlocks[DCTBlockNum].m_lpsData,  (DeZigzagIndex0 + 64 * lpBlocks[DCTBlockNum].m_cM0));
    }

    //Luma blocks
    for(DCTBlockNum=0; DCTBlockNum<4; DCTBlockNum++)
    {
        if (maxA[DCTBlockNum] < 36)
            lpBlocks[DCTBlockNum].m_cC1C0 = (Ipp8u)(maxA[DCTBlockNum] / 12);
        else lpBlocks[DCTBlockNum].m_cC1C0 = 3;
    }

    //Cr block
    if (maxA[4] < 24) //iMaxAC=24;
        lpBlocks[4].m_cC1C0 = (Ipp8u)(maxA[4] / 12)  + 1;
    else lpBlocks[4].m_cC1C0 = 3;

    //Cb block
    if (maxA[5] < 12)
        lpBlocks[5].m_cC1C0 = 2;
    else lpBlocks[5].m_cC1C0 = 3;

} //void ZigZagMBlock(MBLOCK *lpMBlock)

inline
static
Ipp32s ZigZag0(Ipp32u** RLmem, Ipp16s *lpsDst,  Ipp8s * DeZigzag)
{
    Ipp32s CurrElem, temp;
    Ipp32u i, FirstElemAfterNonZeroElem = 1, *tempRL = *RLmem;
    Ipp32s MaxAmp = 0;

    *tempRL++ = lpsDst[0];
    for (i = 1;i < 64;i++)
    {
        CurrElem = lpsDst[DeZigzag[i]];
        if(CurrElem)
        {
            temp = (CurrElem & 0x8000) | (i << 8) | (i - FirstElemAfterNonZeroElem);
            CurrElem = abs(CurrElem);
            temp |= (CurrElem << 16);
            if(CurrElem > MaxAmp)
                MaxAmp = CurrElem;
            *tempRL++ = temp;
            FirstElemAfterNonZeroElem = i + 1;
        }
    }
    *tempRL++ = 0x4000;
    *RLmem = tempRL;
    return MaxAmp;
} //void ZigZag0(...)

}//namespace UMC

#endif //(UMC_ENABLE_DV_VIDEO_ENCODER)
